package com.astrocsr.business;

import java.sql.Blob;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Locale;

import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.astrocsr.common.Constants;
import com.astrocsr.common.helper.EncryptionHelper;
import com.astrocsr.domain.bean.TblUser;
import com.astrocsr.domain.bean.TblUserAccount;
import com.astrocsr.domain.bean.TblUserReport;
import com.astrocsr.domain.bean.TblUserRole;
import com.astrocsr.domain.web.Item;
import com.astrocsr.domain.web.UserAccount;
import com.astrocsr.domain.web.UserInfo;
import com.astrocsr.domain.web.UserReport;

@Service("userManager")
@Transactional(value = "transactionManager", propagation = Propagation.REQUIRED)
public class UserManager extends BaseManager {

	/**
	 * Get user by email
	 */
	public UserInfo getUserByEmail(String email) throws Exception {
		List<TblUser> tblUserList = getUserDAO().findByEmail(email);
		UserInfo userInfo = null;
		if (tblUserList != null && tblUserList.size() > 0) {
			TblUser tblUser = tblUserList.get(0);
			userInfo = new UserInfo();
			BeanUtils.copyProperties(tblUser, userInfo);
			
			String role = Constants.ROLE_USER;
			List<TblUserRole> tblUserRoleList = getUserRoleDAO().findByUserId(userInfo.getUserId());
			if (tblUserRoleList != null && tblUserRoleList.size() > 0) {
				role = tblUserRoleList.get(0).getRoleCode();
			}
			userInfo.setRole(role);
		}
		return userInfo;

	}
	
	public UserInfo getUserById(Long id) throws Exception {
		TblUser tblUser = getUserDAO().findById(id);
		UserInfo userInfo = null;
		if (tblUser != null) {
			userInfo = new UserInfo();
			BeanUtils.copyProperties(tblUser, userInfo);
		}
		return userInfo;

	}
	/**
	 * List all users
	 */
	public List<UserInfo> listUser() throws Exception {

		List<UserInfo> userList = null;
		List<TblUser>  tblUserList = getUserDAO().listTblUser(); 

		if (tblUserList != null && tblUserList.size() > 0) {
			userList = new ArrayList<UserInfo>();
			UserInfo userInfo = null;
			for (TblUser tblUser : tblUserList) {
				userInfo = new UserInfo();
				BeanUtils.copyProperties(tblUser, userInfo);
				userList.add(userInfo);
			}
		}

		return userList;
	}

	/**
	 * This method insert data into USER table
	 */
	public void addUser(UserInfo user) throws Exception {
		if (user != null) {
			TblUser tblUser = new TblUser();
			
			tblUser.setEmail(user.getEmail());
			tblUser.setStatus(user.getStatus());
			// MD5 password
			tblUser.setPassword(EncryptionHelper.encodeMD5(user.getPassword()));
			tblUser.setCreatedDate(new Date());
			tblUser.setUpdatedDate(new Date());
			// Call DAO layer to insert user into database
			getUserDAO().addTblUser(tblUser);
		}		
	}

	/**
	 * Change password
	 */
	public void updatePassword(UserInfo userInfo) throws Exception {
		
		TblUser tblUser = new TblUser();
		tblUser.setUserId(userInfo.getUserId());
		tblUser.setEmail(userInfo.getEmail());
		tblUser.setPassword(EncryptionHelper.encodeMD5(userInfo.getPassword()));
		tblUser.setUpdatedDate(new Date());
		getUserDAO().updatePassword(tblUser);
		
	}

	/**
	 * List User Report
	 */
	public List<UserReport> listUserReport(String email) throws Exception {

		List<UserReport> userReportList = null;
		// do nothing now

		return userReportList;
	}
	
	/**
	 * Get User Report
	 */
	public UserReport getUserReport(Long id) throws Exception {
		
		TblUserReport  tblUserReport = getUserReportDAO().findById(id); 
		UserReport userReport = null;
		if (tblUserReport != null) {
			userReport = new UserReport();
			userReport.setUserReportId(tblUserReport.getUserReportId());
			userReport.setUserId(tblUserReport.getUserId());
			
			Blob reportBLOB = tblUserReport.getReportBLOB();
			byte[] reportData = null;
			if (reportBLOB != null) {
				try {
					reportData = reportBLOB.getBytes(1, (int)reportBLOB.length()).clone();
				} catch (SQLException e) {
					e.printStackTrace();
				}
			}
			userReport.setReportBLOB(reportData);
		}
		
		return userReport;
	}
	
	public List<UserAccount> listUserAccount(Long userId) throws Exception {
		List<TblUserAccount> tblUserAccountList = getUserAccountDAO().listUserAccount(userId);
		List<UserAccount> userAccountList = null;
		
		if (tblUserAccountList != null && tblUserAccountList.size() > 0) {
			userAccountList = new ArrayList<UserAccount>();
			UserAccount userAccount = null;
			for (TblUserAccount tblUserAccount : tblUserAccountList) {
				userAccount = new UserAccount();
				BeanUtils.copyProperties(tblUserAccount, userAccount);
				userAccountList.add(userAccount);
			}
		}
		
		return userAccountList;
	}

	/**
	 * Build date
	 */
	public List<Item> buildMonths(int num) throws Exception {
		List<Item> list = new ArrayList<Item>();
		Calendar cal = Calendar.getInstance();
		Item item = null;
		for (int i = 0; i < num; i++) {
			item = new Item();
			item.setItemName(cal.getDisplayName(Calendar.MONTH, Calendar.SHORT, Locale.ENGLISH) + "-" + cal.get(Calendar.YEAR));
			item.setItemValue((cal.get(Calendar.MONTH)+1) + "-" + cal.get(Calendar.YEAR));
			cal.add(Calendar.MONTH, -1);
			list.add(item);
		}
		return list;
	}
	
}